/*
 * Copyright (c) 2015 Razeware LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import CoreData
import UIKit

class DevicesTableViewController: UITableViewController {
    var coreDataStack: CoreDataStack!
    var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>?
    var selectedPerson: Person?

    override func viewDidLoad() {
        super.viewDidLoad()

        if let selectedPerson = selectedPerson {
            title = "\(selectedPerson.name)'s Devices"
        } else {
            title = "Devices"
            navigationItem.rightBarButtonItems = [
                UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addDevice)),
                UIBarButtonItem(title: "Filter", style: .plain, target: self, action: #selector(selectFilter))
            ]
        }

        let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Device")
        fetchRequest.sortDescriptors = [
            NSSortDescriptor(key: "deviceType.name", ascending: true),
            NSSortDescriptor(key: "name", ascending: true)
        ]

        fetchedResultsController = NSFetchedResultsController(
            fetchRequest: fetchRequest,
            managedObjectContext: coreDataStack.managedObjectContext,
            sectionNameKeyPath: "deviceType.name", cacheName: nil)
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        reloadData()
    }

    func reloadData(predicate: NSPredicate? = nil) {
        guard let fetchedResultsController = fetchedResultsController else {
            return
        }

        if let selectedPerson = selectedPerson {
            fetchedResultsController.fetchRequest.predicate =
                NSPredicate(format: "owner == %@", selectedPerson)
        } else {
            fetchedResultsController.fetchRequest.predicate = predicate
        }

        do {
            try fetchedResultsController.performFetch()
        } catch {
            fatalError("There was an error fetching the list of devices!")
        }

        tableView.reloadData()
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        return fetchedResultsController?.sections?.count ?? 0
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return fetchedResultsController?.sections?[section].name
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fetchedResultsController?.sections?[section].numberOfObjects ?? 0
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "DeviceCell", for: indexPath as IndexPath)

        let device = fetchedResultsController?.object(at: indexPath as IndexPath) as! Device

        cell.textLabel?.text = device.deviceDescription

        if let owner = device.owner {
            cell.detailTextLabel?.text = owner.name
        } else {
            cell.detailTextLabel?.text = "No owner"
        }

        return cell
    }

    // MARK: - Actions & Segues

    @objc func selectFilter(sender: AnyObject?) {
    let sheet = UIAlertController(title: "Filter Options", message: nil, preferredStyle: .actionSheet)

    sheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (_) -> Void in
    }))

    sheet.addAction(UIAlertAction(title: "Show All", style: .default, handler: { (_) -> Void in
        self.reloadData()
    }))

    sheet.addAction(UIAlertAction(title: "Only Owned Devices", style: .default, handler: { (_) -> Void in
        self.reloadData(predicate: NSPredicate(format: "owner != nil"))
    }))

    sheet.addAction(UIAlertAction(title: "Only Phones", style: .default, handler: { (_) -> Void in
        self.reloadData(predicate: NSPredicate(format: "deviceType.name =[c] 'iphone'"))
    }))

    sheet.addAction(UIAlertAction(title: "Only Watches", style: .default, handler: { (_) -> Void in
        self.reloadData(predicate: NSPredicate(format: "deviceType.name =[c] 'watch'"))
    }))

    present(sheet, animated: true, completion: nil)
}

    @objc func addDevice(sender: AnyObject?) {
        performSegue(withIdentifier: "deviceDetail", sender: self)
    }

    func shouldPerformSegueWithIdentifier(identifier: String, sender: AnyObject?) -> Bool {
        if selectedPerson != nil, identifier == "deviceDetail" {
            return false
        }

        return true
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if let dest = segue.destination as? DeviceDetailTableViewController {
            dest.coreDataStack = coreDataStack

            if let selectedIndexPath = tableView.indexPathForSelectedRow {
                let device = fetchedResultsController?.object(at: selectedIndexPath) as! Device
                dest.device = device
            }
        }
    }
}
